Skip to main content

Using Video Node

The VideoNode is a node class in Dora SSR that allows you to play video files in your game scenes. It inherits from Sprite, which means you can use all the properties and methods available to sprite nodes, such as positioning, scaling, rotation, and more. Once a VideoNode is mounted to the game scene, it will automatically start playing the video and continue playing until the node is removed from the scene.

This tutorial will guide you through using VideoNode, including how to prepare video files in the correct format and how to use VideoNode in your game.

1. Video Format Requirements

VideoNode accepts an Ogg container with a Theora video stream. Files are read through Dora Content, so packaged resources and mounted archives use the same path rules as other assets.

1.1 Supported Video Format

  • Container: Ogg (.ogv)
  • Video codec: Theora
  • Color format: Theora 4:2:0, 4:2:2, and 4:4:4 streams are accepted and converted to RGBA for rendering
  • Audio: VideoNode renders video only. Love Video may separately synchronize an audio Source through Dora SoLoud.
  • Resolution/performance:
    • 4K and high-bitrate streams may be CPU intensive for software decoding
    • For smooth playback on mid-range devices, 720p/1080p and moderate bitrates are recommended

1.2 Converting Videos Using FFmpeg

Use an FFmpeg build with the libtheora encoder to create an Ogg/Theora file:

Converting MP4 to Ogg/Theora

# Basic conversion
ffmpeg -i input.mp4 -c:v libtheora -q:v 7 -pix_fmt yuv420p -an output.ogv

# With specific resolution and bitrate (recommended for better performance)
ffmpeg -i input.mp4 -c:v libtheora -q:v 7 -pix_fmt yuv420p -s 1280x720 -r 30 -an output.ogv

# For 1080p video
ffmpeg -i input.mp4 -c:v libtheora -q:v 7 -pix_fmt yuv420p -s 1920x1080 -r 30 -an output.ogv

Parameter explanations:

  • -c:v libtheora: Use the Theora encoder
  • -q:v 7: Select video quality (adjust for size and quality)
  • -pix_fmt yuv420p: Set pixel format to YUV 4:2:0
  • -s 1280x720: Set resolution (optional, adjust as needed)
  • -r 30: Set frame rate to 30 fps (optional, adjust as needed)
  • -an: Remove audio track

Converting Other Formats

# Convert from AVI
ffmpeg -i input.avi -c:v libtheora -q:v 7 -pix_fmt yuv420p -an output.ogv

# Convert from MOV
ffmpeg -i input.mov -c:v libtheora -q:v 7 -pix_fmt yuv420p -an output.ogv
Tip

After conversion, keep the .ogv extension and place the file in the project's Content resource tree.

2. Creating a VideoNode Instance

To create a VideoNode, you need to provide the path to the video file. The VideoNode constructor accepts two parameters:

  • filename: The Content path to an Ogg/Theora video file (normally .ogv)
  • looped: (Optional) Whether the video should loop. Default is false
local VideoNode <const> = require("VideoNode")

-- Create a VideoNode that plays once
local video = VideoNode("assets/video.ogv")

-- Create a VideoNode that loops
local loopingVideo = VideoNode("assets/video.ogv", true)
Important

If the video file cannot be loaded or the format is incorrect, VideoNode() will return nil (or null in TypeScript). Always check if the node was created successfully before using it.

3. Mounting VideoNode to the Scene

Once you create a VideoNode instance, you need to mount it to the game scene for it to be displayed and start playing. When a VideoNode is mounted to the scene, it will automatically begin playing the video and continue playing until the node is removed from the scene.

local VideoNode <const> = require("VideoNode")
local Vec2 <const> = require("Vec2")

-- Create a VideoNode
local video = VideoNode("assets/video.ogv")

if video then
-- Set position
video.position = Vec2(400, 300)

-- Mount to the scene (video will start playing automatically)
-- The video will continue playing as long as the node is in the scene
end
Automatic Playback

Once a VideoNode is mounted to the game scene, it will automatically start playing the video. The video will continue playing frame by frame as long as the node remains in the scene tree. If you set looped to true, the video will automatically restart from the beginning when it reaches the end.

4. Controlling Video Playback

Since VideoNode inherits from Sprite, you can use all sprite properties and methods to control the video display:

local VideoNode <const> = require("VideoNode")
local Vec2 <const> = require("Vec2")
local Scale <const> = require("Scale")

local video = VideoNode("assets/video.ogv", true) -- Loop enabled

if video then
-- Position the video
video.position = Vec2(400, 300)

-- Scale the video
video.scaleX = 0.5
video.scaleY = 0.5

-- Rotate the video
video.angle = 45

-- Set opacity
video.opacity = 0.8

-- Or use action to animate
video:perform(Scale(2.0, 0.5, 1.0)) -- Scale from 0.5 to 2.0 over 1 second
end

5. Removing VideoNode from Scene

To stop the video playback, simply remove the VideoNode from the scene:

-- Remove the video node from its parent (stops playback)
video:removeFromParent()

6. Complete Example

Here's a complete example that demonstrates creating a VideoNode, positioning it, and handling it in a game scene:

local VideoNode <const> = require("VideoNode")
local Vec2 <const> = require("Vec2")
local Size <const> = require("Size")

-- Create a looping video node
local video = VideoNode("assets/background_video.ogv", true)

if video then
-- Scale to fit screen if needed
local visualSize = App.visualSize
local videoSize = video.size
local scaleX = visualSize.width / videoSize.width
local scaleY = visualSize.height / videoSize.height
local scale = math.min(scaleX, scaleY)
video.scaleX = scale
video.scaleY = scale

-- Video will start playing automatically when mounted to scene
-- It will continue playing and loop as long as the node is in the scene
end

7. Performance Considerations

When using VideoNode, keep the following performance tips in mind:

  1. Resolution: Use appropriate resolutions (720p or 1080p) for your target devices. Higher resolutions require more CPU power for decoding.

  2. Bitrate: Moderate bitrates provide a good balance between quality and performance. Very high bitrates can cause stuttering on lower-end devices.

  3. Frame Rate: Constant frame rates (CFR) are recommended. Variable frame rates may cause timing issues.

  4. Multiple Videos: Playing multiple videos simultaneously can be CPU intensive. Consider limiting the number of concurrent VideoNodes.

  5. Background Processing: VideoNode uses a background thread for decoding, which helps maintain smooth gameplay, but still requires CPU resources.

8. Conclusion

In this tutorial, you learned how to:

  • Prepare video files in the correct Ogg/Theora format using FFmpeg
  • Create VideoNode instances
  • Mount VideoNodes to the game scene (which automatically starts playback)
  • Control video display using Sprite properties
  • Handle video looping

Remember that VideoNode will automatically start playing when mounted to the scene and continue playing as long as it remains in the scene tree. This makes it perfect for background videos, cutscenes, or any scenario where you need continuous video playback in your game.

For more information about VideoNode, refer to the VideoNode API documentation.